package com.lkdont.android.base.util

import android.util.Log

/**
 * 日志工具
 *
 * @author lkdont
 */
object Logger {

    const val LEVEL_VERBOSE = 1
    const val LEVEL_DEBUG = 2
    const val LEVEL_INFO = 3
    const val LEVEL_WARNING = 4
    const val LEVEL_ERROR = 5

    private val enableLevels = HashSet<Int>(5)

    /**
     * 允许输出指定等级[levels]的日志
     */
    @Synchronized
    fun enable(vararg levels: Int) {
        for (level in levels) {
            if (level !in (1..5)) {
                throw IllegalArgumentException("level只能为[LEVEL_VERBOSE, LEVEL_DEBUG, LEVEL_INFO, LEVEL_WARNING, LEVEL_ERROR]其中之一")
            }
            enableLevels.add(level)
        }
    }

    /**
     * 允许输出所有等级的日志
     */
    @Synchronized
    fun enableAll() {
        enable(LEVEL_VERBOSE, LEVEL_DEBUG, LEVEL_INFO, LEVEL_WARNING, LEVEL_ERROR)
    }

    /**
     * 禁止输出所有等级的日志
     */
    @Synchronized
    fun disableAll() {
        enableLevels.clear()
    }

    /*** 是否允许打印日志 */
    private fun isLogEnable(level: Int): Boolean {
        return enableLevels.contains(level)
    }

    private fun print(level: Int, tag: String?, msg: String?) {
        when (level) {
            LEVEL_VERBOSE -> {
                Log.v(tag, msg ?: "NULL")
            }
            LEVEL_DEBUG -> {
                Log.d(tag, msg ?: "NULL")
            }
            LEVEL_INFO -> {
                Log.i(tag, msg ?: "NULL")
            }
            LEVEL_WARNING -> {
                Log.w(tag, msg ?: "NULL")
            }
            LEVEL_ERROR -> {
                Log.e(tag, msg ?: "NULL")
            }
        }
    }

    private fun getTag(tag: Any?): String? {
        val clazz = tag?.javaClass ?: return "NULL"
        if (clazz.isAnonymousClass) {
            val tagStr = "$tag"
            return try {
                tagStr.substring(tagStr.lastIndexOf(".") + 1, tagStr.lastIndexOf("$"))
            } catch (e: Exception) {
                "NULL"
            }
        }
        return tag.javaClass.simpleName
    }

    fun v(tag: String?, msg: String?) {
        if (!isLogEnable(LEVEL_VERBOSE)) {
            return
        }
        print(LEVEL_VERBOSE, tag, msg)
    }

    fun v(tag: Any?, msg: String?) {
        if (!isLogEnable(LEVEL_VERBOSE)) {
            return
        }
        v(getTag(tag), msg)
    }

    fun d(tag: String?, msg: String?) {
        if (!isLogEnable(LEVEL_DEBUG)) {
            return
        }
        print(LEVEL_DEBUG, tag, msg)
    }

    fun d(tag: Any?, msg: String?) {
        if (!isLogEnable(LEVEL_DEBUG)) {
            return
        }
        d(getTag(tag), msg)
    }

    fun i(tag: String?, msg: String?) {
        if (!isLogEnable(LEVEL_INFO)) {
            return
        }
        print(LEVEL_INFO, tag, msg)
    }

    fun i(tag: Any?, msg: String?) {
        if (!isLogEnable(LEVEL_INFO)) {
            return
        }
        i(getTag(tag), msg)
    }

    fun w(tag: String?, msg: String?) {
        if (!isLogEnable(LEVEL_WARNING)) {
            return
        }
        print(LEVEL_WARNING, tag, msg)
    }

    fun w(tag: Any?, msg: String?) {
        if (!isLogEnable(LEVEL_WARNING)) {
            return
        }
        w(getTag(tag), msg)
    }

    fun e(tag: String?, msg: String?) {
        if (!isLogEnable(LEVEL_ERROR)) {
            return
        }
        print(LEVEL_ERROR, tag, msg)
    }

    fun e(tag: Any?, msg: String?) {
        if (!isLogEnable(LEVEL_ERROR)) {
            return
        }
        e(getTag(tag), msg)
    }
}